package by.dvrudenko.avtobaza.webapp.page.car.panel;

import java.util.Iterator;

import javax.inject.Inject;
import javax.persistence.metamodel.SingularAttribute;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.OrderByBorder;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import by.dvrudenko.avtobaza.datamodel.Car;
import by.dvrudenko.avtobaza.datamodel.Car_;
import by.dvrudenko.avtobaza.services.CarService;
import by.dvrudenko.avtobaza.webapp.page.AbstractPanel;
import by.dvrudenko.avtobaza.webapp.page.car.CreateCarPage;
import by.dvrudenko.avtobaza.webapp.utils.security.SecuredChekBoxDriverAjax;
import by.dvrudenko.avtobaza.webapp.utils.security.SecuredLinkForAdmin;
import by.dvrudenko.avtobaza.webapp.utils.security.SecuredLinkForAdminAjax;
import by.dvrudenko.avtobaza.webapp.utils.security.SecuredLinkForDriverAjax;

public class CarListPanel extends AbstractPanel {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(CarListPanel.class);

	@Inject
	private CarService carService;

	public CarListPanel(String id) {
		super(id);
		LOGGER.info("beggin create CarListPanel");
		setOutputMarkupId(true);
		CarDataProvider carDataProvider = new CarDataProvider();

		final WebMarkupContainer tableBody = new WebMarkupContainer("wrapper-body"); 
		add(tableBody);

		DataView<Car> dataView = new DataView<Car>("list", carDataProvider, 5) {
			@Override
			protected void populateItem(Item<Car> item) {
				final Car car = item.getModelObject();				
				
				item.add(new Label("carType.brand"));				
				item.add(new Label("carType.model"));
				item.add(new Label("carType.body"));
				item.add(new Label("carType.type"));			
				item.add(new Label("year", handleYear(car.getYear())));
				
				
				// чек бокс с состоянием машины, будет виден только Driver и Admin
				final AjaxCheckBox checkBoxCarCondition =new SecuredChekBoxDriverAjax("carCondition"){
					@Override
					protected void onUpdate(AjaxRequestTarget target) {
						target.add(this);					
					}
				};	
				checkBoxCarCondition.setOutputMarkupId(true);
				checkBoxCarCondition.setEnabled(false);				
				item.add(checkBoxCarCondition);
				
				
				final Model<String> str = handleValueCarCondition(car);
				final Label carConditionString = new Label("carConditionString", str);
				carConditionString.setOutputMarkupId(true);
				item.add(carConditionString);
				
				// ссылки для изменения состояния машины
				final AjaxLink<Void> changeCarCondition;   
				final AjaxLink<Void> saveCarCondition;
				
				// ссылка для изменения состояния машины, видна только Driver и Admin
				changeCarCondition = new SecuredLinkForDriverAjax("changeCarStatus") {
					@Override
					public void onClick(AjaxRequestTarget target) {			
							checkBoxCarCondition.setEnabled(true);
							LOGGER.info(user.getId() + user.getLogin() + "  click link changeCarStatus");
							target.add(checkBoxCarCondition);						
					}
				};
				item.add(changeCarCondition);	
				
				// ссылка для сохранения измененного сотояния машины
				 saveCarCondition = new SecuredLinkForDriverAjax("saveCarStatus") {			
						@Override
						public void onClick(AjaxRequestTarget target) {
							car.setCarCondition(checkBoxCarCondition.getModelObject());
							carService.saveOrUpdate(car);						
							target.add(checkBoxCarCondition);
							//в чек бокс устанавливается новое значение состояния машины
							str.setObject(car.getCarCondition().equals(true)?"рабочая":"поломаная");
							target.add(carConditionString);
							LOGGER.info(" save change CarCondition carId:"+ 
							car.getId() +"condition: " +car.getCarCondition()+ " " + user.getLogin());
							checkBoxCarCondition.setEnabled(false);
						}
					};
				
				item.add(saveCarCondition);
				
				// если машина уехала (не находится в гараже), то поменять ее состояние на поломоную нельзя
				if(car.getWork().equals(true)){
					changeCarCondition.setVisible(false);
					saveCarCondition.setVisible(false);
				}
				
				item.add(new Label("work", handleValueCarWork(car)));
				//item.add(new Label("image"));
				item.add(new Label("carryingCapacity"));
				item.add(new Label("volumeCapacity"));
				//item.add(new Label("numberOfSeats"));
				item.add(new Label("bodyLength"));
				item.add(new Label("bodyWidth"));
				item.add(new Label("carNumber"));
							
				
				// ссылка для редактирования машины, видна только Admin
				Link edit = new SecuredLinkForAdmin("edit"){
					@Override
					public void onClick() {
						LOGGER.info("user edit Car, carId:"+ 
								car.getId() + user.getLogin());
						setResponsePage(new CreateCarPage(car));
					}
				};
				item.add(edit);
				
				//  ссылка для удаления
				item.add(new SecuredLinkForAdminAjax("remove-ajax") {
					@Override
					public void onClick(AjaxRequestTarget target) {
						carService.delete(car);
						LOGGER.info("delete Car, userLogin - :"+user.getLogin());
						info(new ResourceModel("p.home.car.createcar.deleteCar").getObject().toString());
						target.addChildren(getPage(), FeedbackPanel.class);	
						target.add(CarListPanel.this);
					}
					
					// если машина уехала, то ее удалить нельзя
					@Override
					protected void onConfigure() {
						super.onConfigure();
						if (!car.getWork().equals(false)){
							setVisible(false);
						};
					}

				});
			}
		};

		tableBody.add(dataView);

		
		add(new MyPagingNavigator("paging", dataView));
		// параметры сортировки
		add(new OrderByBorder<SingularAttribute<Car, ?>>("sortBycarryingCapacity", Car_.carryingCapacity, carDataProvider));
		add(new OrderByBorder<SingularAttribute<Car, ?>>("sortByvolumeCapacity", Car_.volumeCapacity, carDataProvider));
		add(new OrderByBorder<SingularAttribute<Car, ?>>("sortByYear", Car_.year, carDataProvider));
		
		//add(new OrderByBorder<SingularAttribute<?, ?>>("sortByYear", Car_.year, carDataProvider));	
	}

	private class CarDataProvider extends SortableDataProvider<Car, SingularAttribute<Car, ?>> {

		public CarDataProvider() {
			super();
			// сортировка по умолчанию
			setSort(Car_.carryingCapacity, SortOrder.ASCENDING);
		}

		@Override
		public Iterator<? extends Car> iterator(long first, long count) {

			SingularAttribute<Car, ?> sortParam = getSort().getProperty();
			SortOrder propertySortOrder = getSortState().getPropertySortOrder(sortParam);
			boolean ascending = SortOrder.ASCENDING.equals(propertySortOrder);
			return carService.getAllCars(sortParam, ascending, (int) first, (int) count).iterator();
		}

		@Override
		public long size() {
			return carService.getCount();
		}

		@Override
		public IModel<Car> model(Car car) {
			return new CompoundPropertyModel<Car>(car);
		}
	}

}
